﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractForeEnd;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.DeviceMsgQueues;
using HamcoWcs.Models.BaseConfigs;
using HamcoWcs.Models.Common;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.DeviceMsgQueues;
using HamcoWcs.Models.DeviceMsgs;
using HamcoWcs.Models.DeviceMsgs.SrmMsgs;
using HamcoWcs.Models.Devices;
using HamcoWcs.Models.Exceptions;
using HamcoWcs.Models.ForeEndModels.Basic;
using HamcoWcs.Models.ForeEndModels.DeviceMsgQueues;
using HamcoWcs.Models.NodeInfos;
using HamcoWcs.Service.Common;
using HamcoWcs.Workers;
using HamcoWcs.Workers.SrmWorkers;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace HamcoWcs.Main.Controllers.Wcs
{
    public class DeviceMsgQueueController : BasicController
    {

        #region Constructor

        private readonly IForeEndDeviceMsgQueueService _deviceMsgQueueService;
        private readonly AutomaticStorageInfo _asrs;
        private readonly IMesCommunicateService _mesCommunicateService;
        public DeviceMsgQueueController(IMesCommunicateService mesCommunicateService, AutomaticStorageInfo asrs, IForeEndDeviceMsgQueueService deviceMsgQueueService, WcsDbContext wcsDbContext, IMapper mapper, ILoggerService logger, IBaseConfigService baseConfigService) : base(logger, mapper, wcsDbContext)
        {
            _deviceMsgQueueService = deviceMsgQueueService;
            _asrs = asrs;
            _mesCommunicateService = mesCommunicateService;
            _baseConfigService = baseConfigService;
        }

        public override string ControllerName => "DeviceMsgQueueController";

        #endregion Constructor
        /*
            {
              "deviceCode": "srm01",
              "request": 6
            }
{
  "machineName": "CJSTW100",
  "portName": "C1",
  "deviceType": 1,
  "request": 7
}
         */
        /// <summary>
        /// 创建新的设备消息队列 
        /// 已读：0 | 入库：1 | 出库：2 | 移库：3 | 直出：4 | 移动：5 | 启动：6 | 停止：7 | 异常解除：8
        /// </summary>
        /// <param name="model"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult CreateNewDeviceMsg(CreateDeviceMsgQueueDto model, [FromHeader] string userName)
        {
            try
            {

                string cmd = "";

                if (model.DeviceType == EnumDeviceType.CV)
                {
                    cmd = ((EnumPconSendMsg)model.Request).ToString();
                }
                else if (model.DeviceType == EnumDeviceType.Srm)
                {
                    cmd = ((EnumSrmSendMsg)model.Request).ToString();
                }
                else
                {
                    throw new WarningException($"错误的设备类型,{model.DeviceType}");
                }

                _deviceMsgQueueService.CreateNewDeviceMsg(model);



                AddOperationLog(userName, $"{model.MachineName}-{model.PortName},{cmd}");
                return Json(ForeEndResult.Ok);

            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return CreateFailureResult();
            }

        }

        /// <summary>
        /// DeviceType:CV=0，SRM=1
        /// </summary>
        /// <param name="model"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UpdateGlobalConfig(UIGlobalConfigModel model, [FromHeader] string userName)
        {
            try
            {
                if (string.IsNullOrEmpty(model.Remark))
                    throw new WarningException("清输入备注");

                if (!(model.DeviceType == 1 || model.DeviceType == 0))
                {
                    throw new WarningException("DeviceType错误，CV=0，SRM=1");
                }

                Dictionary<string, GlobalConfigModel> a;
                if (model.DeviceType == 0)
                {
                    a = GlobalValue.PconGlobalConfigs;
                }
                else
                {
                    a = GlobalValue.SrmGlobalConfigs;
                }

                var b = a.TryGetValue(model.Name, out GlobalConfigModel cfg);

                if (!b) throw new WarningException($"未找到配置{model.Name}");

                cfg.NewValue = model.Value;

                AddOperationLog(userName, $"{userName}设置参数{model.Name}:{model.Value}({model.Remark})");
                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return UpdateFailureResult();
            }
        }

        /// <summary>
        /// 全局控制
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GlobalControl(GlobalControlModel model, [FromHeader] string userName = "")
        {


            try
            {
                if (model.Command < 3 || model.Command > 5)
                {
                    throw new WarningException("传入的全局控制指令错误");
                }

                var pconEntity = _wcsDbContext.PconInfos.FirstOrDefault(x => x.PconName == "9999")
                    ?? throw new WarningException("未找到全局控制的块");

                var pcon = _mapper.Map<PconDto>(pconEntity);
                //var pcon = _asrs.Pcons.FirstOrDefault(x => x.PconName == 9999)

                var pconMsg = new PconSendMsg()
                {
                    PconName = (ushort)pcon.PconName,
                    Request = (ushort)model.Command
                };

                var deviceMsgQueueDto = new DeviceMsgQueueDto(pcon, pconMsg);

                var deviceMsgQueue = _mapper.Map<DeviceMsgQueue>(deviceMsgQueueDto);
                _wcsDbContext.Add(deviceMsgQueue);
                _wcsDbContext.SaveChanges();
                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return UnknownExceptionResult();
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ChangeChannelMachineControlState(ChangeMachineControlStateModel model, [FromHeader] string userName = "")
        {
            try
            {
                if (!(model.State == "OFFLINE" || model.State == "ONLINEREMOTE"))
                    throw new WarningException("错误的State");

                var a = Enum.TryParse<EnumMachineControlState>(model.State, out EnumMachineControlState state);
                if (!a) throw new WarningException("错误的State");


                if (!(model.MachineName == "CJSTW100" || model.MachineName == "CJSTW200"))
                    throw new WarningException("错误的MachineName");

                _mesCommunicateService.MachineControlStateChanged(new NodeInfoDto()
                {
                    NodeName = model.MachineName,
                    MachineControlState = state
                });

                var k = $"{model.MachineName}CONTROLSTATE";
                _baseConfigService.SetConfigMsg(k, ((int)state).ToString());

                AddOperationLog(userName, $"{userName}切换{model.MachineName}控制状态为{model.State}");
                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return UpdateFailureResult();
            }
        }

        /// <summary>
        /// 堆垛机回原点
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SrmReturnHome(SrmReturnHomeModel model, [FromHeader] string userName = "")
        {
            try
            {
                var srm = _asrs.Srms.Where(x => x.MachineName == model.MachineName)
                    .Where(x => x.PortName == model.PortName)
                    .FirstOrDefault()
                    ?? throw new WarningException($"未找到设备{model.MachineName}-{model.PortName}");

                if (srm.IsTask == 1) throw new WarningException($"{srm.DeviceName}当前有任务");

                ushort row = 0;
                ushort bay = 0;

                if (srm.MachineName == "CJSTW100" && srm.PortName == "C1")
                {
                    row = 1;
                    bay = 1;
                }
                else if (srm.MachineName == "CJSTW100" && srm.PortName == "C2")
                {
                    row = 1;
                    bay = 42;
                }
                else if (srm.MachineName == "CJSTW200" && srm.PortName == "C1")
                {
                    row = 3;
                    bay = 1;
                }
                else if (srm.MachineName == "CJSTW200" && srm.PortName == "C2")
                {
                    row = 3;
                    bay = 59;
                }

                var srmMsg = new SrmSendMsg(false)
                {
                    ToRow = row,
                    ToBay = bay,
                    ToLev = 1,
                    Request = 5
                };

                var deviceMsgQueueDto = new DeviceMsgQueueDto(srm, srmMsg);

                AddOperationLog(userName, $"{userName},{srm.DeviceName}:ReturnHome");

                var deviceMsgQueue = _mapper.Map<DeviceMsgQueue>(deviceMsgQueueDto);
                _wcsDbContext.Add(deviceMsgQueue);
                _wcsDbContext.SaveChanges();

                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return UpdateFailureResult();
            }
        }

        /// <summary>
        /// 修改Port状态
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ChangePortState(ChangePortStateModel model, [FromHeader] string userName = "")
        {
            try
            {
                var con = _asrs.Pcons.Where(x => x.MachineName == model.MachineName)
                    .Where(x => x.PortName == model.PortName)
                    .FirstOrDefault()
                    ?? throw new WarningException($"未找到设备{model.MachineName}-{model.PortName}");

                if (con.MachineName.Contains("CJRCV") && con.WorkType == 1 && con.IsGoods == 1 && con.PortName == "02")
                {
                    con.PortState = "UR";
                    _mesCommunicateService.PortTransferStateChanged(con);
                    AddOperationLog(userName, $"{userName}切换{model.MachineName}Port状态为{con.PortState}");
                }

                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return UpdateFailureResult();
            }
        }



        /// <summary>
        /// 获取货位Teach值
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetSrmTeach(GetSrmTeachRequestModel model)
        {
            try
            {
                if (string.IsNullOrEmpty(model.ShelfName)) throw new WarningException("请传入货位名");
                if (!model.ShelfName.IsShelf()) throw new WarningException("请传入正确的货位名");

                var m = GetSrmTeachModel.Build(model);

                if (GlobalValue.SrmTeachRequestQueue.Any(x => x.ShelfName == m.ShelfName))
                {
                    throw new WarningException("该请求已经在队列中，请等待结果");
                }
                else
                {
                    GlobalValue.SrmTeachRequestQueue.Enqueue(m);
                }

                return Json(ForeEndResult.Ok);
            }
            catch (WarningException ex)
            {
                return Warning(ex);
            }
            catch (System.Exception ex)
            {
                AddSystemLog(ex.Message);
                return UnknownExceptionResult();
            }
        }

        private readonly IBaseConfigService _baseConfigService;
    }
}
